1use crate::ast::*;
2use crate::ast::statements::control_flow::{ForInStatement, ForOfStatement};
3
4pub mod default_visitor;
5pub use default_visitor::{DefaultVisitor, NodeCounter};
6
7pub trait Visitor {
8 type Output;
9
10 fn visit_node(&mut self, node: &Node) -> Self::Output {
11 match node {
12 Node::Program(program) => self.visit_program(program),
13 Node::VariableDeclaration(decl) => self.visit_variable_declaration(decl),
14 Node::FunctionDeclaration(decl) => self.visit_function_declaration(decl),
15 Node::ClassDeclaration(decl) => self.visit_class_declaration(decl),
16 Node::BinaryExpression(expr) => self.visit_binary_expression(expr),
17 Node::UnaryExpression(expr) => self.visit_unary_expression(expr),
18 Node::CallExpression(expr) => self.visit_call_expression(expr),
19 Node::NewExpression(expr) => self.visit_new_expression(expr),
20 Node::MemberExpression(expr) => self.visit_member_expression(expr),
21 Node::AssignmentExpression(expr) => self.visit_assignment_expression(expr),
22 Node::ConditionalExpression(expr) => self.visit_conditional_expression(expr),
23 Node::LogicalExpression(expr) => self.visit_logical_expression(expr),
24 Node::UpdateExpression(expr) => self.visit_update_expression(expr),
25 Node::BlockStatement(stmt) => self.visit_block_statement(stmt),
26 Node::IfStatement(stmt) => self.visit_if_statement(stmt),
27 Node::ForStatement(stmt) => self.visit_for_statement(stmt),
28 Node::ForInStatement(stmt) => self.visit_for_in_statement(stmt),
29 Node::ForOfStatement(stmt) => self.visit_for_of_statement(stmt),
30 Node::WhileStatement(stmt) => self.visit_while_statement(stmt),
31 Node::DoWhileStatement(stmt) => self.visit_do_while_statement(stmt),
32 Node::SwitchStatement(stmt) => self.visit_switch_statement(stmt),
33 Node::TryStatement(stmt) => self.visit_try_statement(stmt),
34 Node::CatchClause(clause) => self.visit_catch_clause(clause),
35 Node::ThrowStatement(stmt) => self.visit_throw_statement(stmt),
36 Node::ReturnStatement(stmt) => self.visit_return_statement(stmt),
37 Node::BreakStatement(stmt) => self.visit_break_statement(stmt),
38 Node::ContinueStatement(stmt) => self.visit_continue_statement(stmt),
39 Node::ExpressionStatement(stmt) => self.visit_expression_statement(stmt),
40 Node::ArrayLiteral(lit) => self.visit_array_literal(lit),
41 Node::ObjectLiteral(lit) => self.visit_object_literal(lit),
42 Node::Property(prop) => self.visit_property(prop),
43 Node::Identifier(id) => self.visit_identifier(id),
44 Node::Number(num) => self.visit_number(*num),
45 Node::String(s) => self.visit_string(s),
46 Node::Boolean(b) => self.visit_boolean(*b),
47 Node::Null => self.visit_null(),
48 Node::Undefined => self.visit_undefined(),
49 Node::This => self.visit_this(),
50 Node::ArrowFunctionExpression(expr) => self.visit_arrow_function_expression(expr),
51 Node::FunctionExpression(expr) => self.visit_function_expression(expr),
52 Node::ClassExpression(expr) => self.visit_class_expression(expr),
53 Node::YieldExpression(expr) => self.visit_yield_expression(expr),
54 Node::AwaitExpression(expr) => self.visit_await_expression(expr),
55 Node::Super(super_expr) => self.visit_super(super_expr),
56 Node::MetaProperty(prop) => self.visit_meta_property(prop),
57 Node::SpreadElement(elem) => self.visit_spread_element(elem),
58 Node::RestElement(elem) => self.visit_rest_element(elem),
59 Node::TemplateLiteral(lit) => self.visit_template_literal(lit),
60 Node::TaggedTemplateExpression(expr) => self.visit_tagged_template_expression(expr),
61 Node::ImportDeclaration(decl) => self.visit_import_declaration(decl),
62 Node::ExportDeclaration(decl) => self.visit_export_declaration(decl),
63 Node::LabeledStatement(stmt) => self.visit_labeled_statement(stmt),
64 Node::WithStatement(stmt) => self.visit_with_statement(stmt),
65 Node::DebuggerStatement(stmt) => self.visit_debugger_statement(stmt),
66 Node::BigInt(bigint) => self.visit_bigint(bigint),
67 Node::RegExp(regexp) => self.visit_regexp(regexp),
68 }
69 }
70
71 fn visit_program(&mut self, program: &Program) -> Self::Output;
72 fn visit_variable_declaration(&mut self, decl: &VariableDeclaration) -> Self::Output;
73 fn visit_function_declaration(&mut self, decl: &FunctionDeclaration) -> Self::Output;
74 fn visit_class_declaration(&mut self, decl: &ClassDeclaration) -> Self::Output;
75 fn visit_binary_expression(&mut self, expr: &BinaryExpression) -> Self::Output;
76 fn visit_unary_expression(&mut self, expr: &UnaryExpression) -> Self::Output;
77 fn visit_call_expression(&mut self, expr: &CallExpression) -> Self::Output;
78 fn visit_new_expression(&mut self, expr: &NewExpression) -> Self::Output;
79 fn visit_member_expression(&mut self, expr: &MemberExpression) -> Self::Output;
80 fn visit_assignment_expression(&mut self, expr: &AssignmentExpression) -> Self::Output;
81 fn visit_conditional_expression(&mut self, expr: &ConditionalExpression) -> Self::Output;
82 fn visit_logical_expression(&mut self, expr: &LogicalExpression) -> Self::Output;
83 fn visit_update_expression(&mut self, expr: &UpdateExpression) -> Self::Output;
84 fn visit_block_statement(&mut self, stmt: &BlockStatement) -> Self::Output;
85 fn visit_if_statement(&mut self, stmt: &IfStatement) -> Self::Output;
86 fn visit_for_statement(&mut self, stmt: &ForStatement) -> Self::Output;
87 fn visit_for_in_statement(&mut self, stmt: &ForInStatement) -> Self::Output;
88 fn visit_for_of_statement(&mut self, stmt: &ForOfStatement) -> Self::Output;
89 fn visit_while_statement(&mut self, stmt: &WhileStatement) -> Self::Output;
90 fn visit_do_while_statement(&mut self, stmt: &DoWhileStatement) -> Self::Output;
91 fn visit_switch_statement(&mut self, stmt: &SwitchStatement) -> Self::Output;
92 fn visit_try_statement(&mut self, stmt: &TryStatement) -> Self::Output;
93 fn visit_catch_clause(&mut self, clause: &CatchClause) -> Self::Output;
94 fn visit_throw_statement(&mut self, stmt: &ThrowStatement) -> Self::Output;
95 fn visit_return_statement(&mut self, stmt: &ReturnStatement) -> Self::Output;
96 fn visit_break_statement(&mut self, stmt: &BreakStatement) -> Self::Output;
97 fn visit_continue_statement(&mut self, stmt: &ContinueStatement) -> Self::Output;
98 fn visit_expression_statement(&mut self, stmt: &ExpressionStatement) -> Self::Output;
99 fn visit_array_literal(&mut self, lit: &ArrayLiteral) -> Self::Output;
100 fn visit_object_literal(&mut self, lit: &ObjectLiteral) -> Self::Output;
101 fn visit_property(&mut self, prop: &Property) -> Self::Output;
102 fn visit_identifier(&mut self, id: &str) -> Self::Output;
103 fn visit_number(&mut self, num: f64) -> Self::Output;
104 fn visit_string(&mut self, s: &str) -> Self::Output;
105 fn visit_boolean(&mut self, b: bool) -> Self::Output;
106 fn visit_null(&mut self) -> Self::Output;
107 fn visit_undefined(&mut self) -> Self::Output;
108 fn visit_this(&mut self) -> Self::Output;
109 fn visit_arrow_function_expression(&mut self, expr: &ArrowFunctionExpression) -> Self::Output;
110 fn visit_function_expression(&mut self, expr: &FunctionExpression) -> Self::Output;
111 fn visit_class_expression(&mut self, expr: &ClassExpression) -> Self::Output;
112 fn visit_yield_expression(&mut self, expr: &YieldExpression) -> Self::Output;
113 fn visit_await_expression(&mut self, expr: &AwaitExpression) -> Self::Output;
114 fn visit_super(&mut self, super_expr: &Super) -> Self::Output;
115 fn visit_meta_property(&mut self, prop: &MetaProperty) -> Self::Output;
116 fn visit_spread_element(&mut self, elem: &SpreadElement) -> Self::Output;
117 fn visit_rest_element(&mut self, elem: &RestElement) -> Self::Output;
118 fn visit_template_literal(&mut self, lit: &TemplateLiteral) -> Self::Output;
119 fn visit_tagged_template_expression(&mut self, expr: &TaggedTemplateExpression) -> Self::Output;
120 fn visit_import_declaration(&mut self, decl: &ImportDeclaration) -> Self::Output;
121 fn visit_export_declaration(&mut self, decl: &ExportDeclaration) -> Self::Output;
122 fn visit_labeled_statement(&mut self, stmt: &LabeledStatement) -> Self::Output;
123 fn visit_with_statement(&mut self, stmt: &WithStatement) -> Self::Output;
124 fn visit_debugger_statement(&mut self, stmt: &DebuggerStatement) -> Self::Output;
125 fn visit_bigint(&mut self, bigint: &str) -> Self::Output;
126 fn visit_regexp(&mut self, regexp: &RegExp) -> Self::Output;
127}